package com.yxf.triangle;

import android.content.Context;
import android.opengl.GLSurfaceView;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
//1,静态导入OpenGL ES2.0包
import static android.opengl.GLES20.*;

public class MyRenderer implements GLSurfaceView.Renderer {

    //5,定义顶点坐标所需数字数量,二维图形只需要x,y两个 , 三维需要x,y,z三个.
    //我们先画个二维的三角形,所以顶点坐标所需数字常量设置为2.
    private static final int POSITION_COMPONENT_COUNT = 2;
    //6,设置三角形的三个顶点坐标: 左下(-0.5f,0f),右下(0.5f,0f),中上(0f,0.5f)
    private float[] triangleVertices = {
            -0.5f,0f,
            0.5f,0f,
            0f,0.5f,
    };

    //7,定义Native的浮点数储存所需字节数
    private static final int BYTES_PER_FLOAT = 4;
    //8,定义Native浮点数缓存的引用
    private final FloatBuffer vertexData;


    private Context context;

    //11,添加program对象Id定义
    private int program;

    //14,定义u_Color和a_Position相关变量
    private static final String U_COLOR = "u_Color";
    private int uColorLocation;
    private static final String A_POSITION = "a_Position";
    private int aPositionLocation;

    public MyRenderer(Context context) {
        this.context = context;

        //9,将三角形顶点数据储存到Native的浮点缓存中
        //注意必须使用ByteBuffer.allocateDirect而不是ByteBuffer.allocate,前者分配的才是不会被垃圾回收的本地内存
        vertexData = ByteBuffer.allocateDirect(triangleVertices.length * BYTES_PER_FLOAT)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        vertexData.put(triangleVertices);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        //2,设置清空屏幕用的颜色
        glClearColor(0f, 1f, 0f, 0f);

        //9,读取shader源文件
        String vertexShaderSource = CommonUtils.readTextFromResource(context, R.raw.triangle_vertex_shader);
        String fragmentShaderSource = CommonUtils.readTextFromResource(context, R.raw.triangle_fragment_shader);

        //10,编译shader 源文件
        int vertexShader = CommonUtils.compileVertexShader(vertexShaderSource);
        int fragmentShader = CommonUtils.compileFragmentShader(fragmentShaderSource);

        //12,将shader添加进program,并获得Program的Id
        program = CommonUtils.linkProgram(vertexShader, fragmentShader);
        //13,使用这个program
        glUseProgram(program);

        //15,获得u_Color和a_Position的位置
        //一个Uniform,一个Attribute别搞错了
        uColorLocation = glGetUniformLocation(program, U_COLOR);
        aPositionLocation = glGetAttribLocation(program, A_POSITION);

        //16,根据a_Position的位置将顶点数据传给a_Position
        vertexData.position(0);
        glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, 0, vertexData);
        //17,激活顶点数组
        glEnableVertexAttribArray(aPositionLocation);

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        //3,设置视口尺寸
        glViewport(0, 0, width, height);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        //4,根据步骤2设置的颜色清空屏幕,注意如果不清空会保留之前的绘制,所以这步一般是必要的
        glClear(GL_COLOR_BUFFER_BIT);
        //18,更新着色器中u_Color的值(r,g,b,a) = (255,255,255,255)
        glUniform4f(uColorLocation, 1f, 1f, 1f, 1f);
        //19,告诉OpenGL,画三角形,从开头读顶点数据开始读,读三个顶点
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }
}
